package com.tongji.diy.view.component3D
{
	import com.tongji.diy.utils.RoomParameters;
	import com.tongji.diy.view.component3D.RoomBorder;
	import com.tongji.diy.view.material.DefaultMaterial;
	
	import flare.core.Mesh3D;
	import flare.core.Pivot3D;
	import flare.core.Surface3D;
	import flare.core.Texture3D;
	import flare.materials.Material3D;
	import flare.materials.Shader3D;
	import flare.materials.filters.ColorFilter;
	import flare.materials.filters.TextureFilter;
	import flare.primitives.Sphere;
	
	import flash.display.BitmapData;
	import flash.display.GradientType;
	import flash.display.Shape;
	import flash.geom.Point;
	import flash.geom.Vector3D;
	
	public class ShapeToAdd extends Pivot3D
	{
		//最后条边的法向量
		protected var dirVec:Point = new Point(0,1);
		
		protected var _roomShapePoints:Vector.<Point>;
		protected var _pos:Vector3D;
		protected var _roomBorder:RoomBorder;
		protected var _material:Material3D;
		
		protected var borders:Vector.<Mesh3D> = new Vector.<Mesh3D>;
		
		public function ShapeToAdd(roomShapePoints:Vector.<Point>, pos:Vector3D, roomBorder:RoomBorder, name:String = "")
		{
			super();
			
			this._roomShapePoints = roomShapePoints;
			this._pos = pos;
			this._roomBorder = roomBorder;
			this._material = roomBorder.material;
		}
		
		public function refresh(pos:Vector3D,roomBorder:RoomBorder):void
		{
			this._roomBorder = roomBorder;
			
			//1.保存材质
			//*2.重绘
			//3.调整位置
			//4.旋转
		}
		
		//换材质
		public function setMat(m:Material3D):void
		{
			this.setMaterial(m,true);
		}
		
		//将位置调整到附着墙的内外墙中线上
		public function setPos(pos:Vector3D, roomBorder:RoomBorder):void
		{
			var start:Point = new Point(roomBorder.start.data.globalX, roomBorder.start.data.globalY);
			var end:Point = new Point(roomBorder.end.data.globalX, roomBorder.end.data.globalY);
			var newPos:Vector3D = new Vector3D();
			var k:Number = 0;
			var b:Number = 0;
			
			if( (end.x - start.x) != 0)
			{
				k = (end.y - start.y)/(end.x - start.x);
				b = start.y - k*start.x;
				
				newPos.x = (pos.x+(pos.z-b)*k)/(1+k*k);
				newPos.z = newPos.x*k+b;
				newPos.y = 0;
			}
			else
			{
				newPos.x = start.x;
				newPos.z = pos.z;
				newPos.y = 0;
			}
			
			this.setPosition(newPos.x, newPos.y, newPos.z, 1, false);
		}
		
		//normal是单位化的Point
		public function setRot(normal:Point):void
		{
			var angle:Number = Math.acos((dirVec.x*normal.x + dirVec.y*normal.y)/(normal.length*dirVec.length))*180/Math.PI;
			
			//单位化normal
			normal.x /= normal.length;
			normal.y /= normal.length;
			
			if(dirVec.x > normal.x)
				this.setRotation(0, -angle, 0);
			else
				this.setRotation(0, angle, 0);
		}
		
		public function get pos():Vector3D
		{
			return this._pos;
		}
		
		public function get roomShapePoints():Vector.<Point>
		{
			return this._roomShapePoints;
		}
		
		public function get roomBorder():RoomBorder
		{
			return this._roomBorder;
		}
		
		public function drawBorder(border:Mesh3D,pre:Point,start:Point,end:Point,next:Point):Mesh3D
		{
			if(border.surfaces.length)
			{
				border.surfaces[0].dispose();
				border.surfaces[1].dispose();
				border.surfaces[2].dispose();
			}
			
			/*
			网格初始化
			*/
			
			//内墙
			border.surfaces[0] = new Surface3D();
			var shader:Shader3D = this._roomBorder.surfaces[0].material.clone() as Shader3D;
			if(shader.filters.length > 1)
				shader.filters.pop();
			border.surfaces[0].material = shader as Material3D;
			border.surfaces[0].addVertexData( Surface3D.POSITION );
			border.surfaces[0].addVertexData( Surface3D.UV0 );
			border.surfaces[0].addVertexData( Surface3D.NORMAL );
			//墙顶
			border.surfaces[1] = new Surface3D();
			border.surfaces[1].material = DefaultMaterial.getInst();
			border.surfaces[1].addVertexData( Surface3D.POSITION );
			border.surfaces[1].addVertexData( Surface3D.UV0 );
			border.surfaces[1].addVertexData( Surface3D.NORMAL );
			//外墙
			border.surfaces[2] = new Surface3D();
			border.surfaces[2].material = DefaultMaterial.getInst();
			border.surfaces[2].addVertexData( Surface3D.POSITION );
			border.surfaces[2].addVertexData( Surface3D.UV0 );
			border.surfaces[2].addVertexData( Surface3D.NORMAL );
			
			/*
			计算墙体数据
			*/
			
			var insidePoint:Point;     //内墙顶点坐标
			var outsidePoint:Point;    //外墙顶点坐标
			var prevVector:Point;      //当前控制点到前一控制点向量
			var nextVector:Point;      //当前控制点到后一控制点向量
			var distance:Number;       //控制点到内外墙点顶点的距离
			
			//前
			prevVector = new Point( pre.x - start.x, pre.y - start.y);
			nextVector = new Point( end.x - start.x, end.y - start.y);
			
			var angle:Number = Math.atan(prevVector.y/prevVector.x) - Math.atan(nextVector.y/nextVector.x);
			if (angle>0)
			{
				angle = angle - Math.PI;
			}
			distance= RoomParameters.wallWidth/Math.sin(angle/2)
			if (angle/2 == 0 )
				distance = RoomParameters.wallWidth;
			
			var prevAngle:Number = Math.atan(prevVector.y/prevVector.x);
			if (prevVector.x<0)
			{
				prevAngle = prevAngle - Math.PI;
			}	
			var nextAngle:Number = Math.atan(nextVector.y/nextVector.x);
			if (nextVector.x<0)
			{
				nextAngle = nextAngle - Math.PI;
			}	
			var middleAngle	:Number = (nextAngle + prevAngle) /2
			
			insidePoint = new Point(start.x + Math.cos(middleAngle) * distance, start.y + Math.sin(middleAngle) * distance);
			if (isClockwise(pre.x,pre.y,start.x,start.y,insidePoint.x,insidePoint.y))
			{
				outsidePoint = new Point(start.x - Math.cos(middleAngle) * distance, start.y - Math.sin(middleAngle) * distance);
			}
			else
			{
				outsidePoint = insidePoint;
				insidePoint = new Point(start.x - Math.cos(middleAngle) * distance, start.y - Math.sin(middleAngle) * distance);
			}
			
			//0
			border.surfaces[0].vertexVector.push(insidePoint.x, 0, insidePoint.y, 0, 0, 0, 1, 1);
			//1
			border.surfaces[0].vertexVector.push(insidePoint.x, RoomParameters.wallHeight, insidePoint.y, 0, 1,  0, 1, 0);
			
			//1
			border.surfaces[1].vertexVector.push(insidePoint.x, RoomParameters.wallHeight, insidePoint.y, 0, 0, 0, 1, 0);
			//2
			border.surfaces[1].vertexVector.push(outsidePoint.x, RoomParameters.wallHeight, outsidePoint.y, 0, 1, 0, 1, 0);
			
			//2
			border.surfaces[2].vertexVector.push(outsidePoint.x, RoomParameters.wallHeight, outsidePoint.y, 1, 1, 0, 1, 0);
			//3
			border.surfaces[2].vertexVector.push(outsidePoint.x, 0, outsidePoint.y, 1, 0, 0, 1, 1);
			
			//后
			prevVector = new Point( start.x - end.x, start.y - end.y);
			nextVector = new Point( next.x - end.x, next.y - end.y);
			angle = Math.atan(prevVector.y/prevVector.x) - Math.atan(nextVector.y/nextVector.x);
			if (angle>0)
			{
				angle = angle - Math.PI;
			}
			distance= RoomParameters.wallWidth/Math.sin(angle/2)
			if (angle/2 == 0 )
				distance = RoomParameters.wallWidth;
			prevAngle = Math.atan(prevVector.y/prevVector.x);
			if (prevVector.x<0)
			{
				prevAngle = prevAngle - Math.PI;
			}	
			nextAngle = Math.atan(nextVector.y/nextVector.x);
			if (nextVector.x<0)
			{
				nextAngle = nextAngle - Math.PI;
			}	
			middleAngle	= (nextAngle + prevAngle) /2
			
			insidePoint = new Point(end.x + Math.cos(middleAngle) * distance, end.y + Math.sin(middleAngle) * distance);
			if (isClockwise(start.x,start.y,end.x,end.y,insidePoint.x,insidePoint.y))
			{
				outsidePoint = new Point(end.x - Math.cos(middleAngle) * distance, end.y - Math.sin(middleAngle) * distance);
			}
			else
			{
				outsidePoint = insidePoint;
				insidePoint = new Point(end.x - Math.cos(middleAngle) * distance, end.y - Math.sin(middleAngle) * distance);
			}
			
			//4
			border.surfaces[0].vertexVector.push(insidePoint.x, 0, insidePoint.y, 1, 0, 0, 1, 1);
			//5
			border.surfaces[0].vertexVector.push(insidePoint.x, RoomParameters.wallHeight, insidePoint.y, 1, 1, 0, 1, 0);
			
			//5
			border.surfaces[1].vertexVector.push(insidePoint.x, RoomParameters.wallHeight, insidePoint.y, 1, 0, 0, 1, 0);
			//6
			border.surfaces[1].vertexVector.push(outsidePoint.x, RoomParameters.wallHeight, outsidePoint.y, 1, 1, 0, 1, 0);
			
			//6
			border.surfaces[2].vertexVector.push(outsidePoint.x, RoomParameters.wallHeight, outsidePoint.y, 0, 1, 0, 1, 0);
			//7
			border.surfaces[2].vertexVector.push(outsidePoint.x, 0, outsidePoint.y, 0, 0, 0, 1, 1);
			
			//内墙
			border.surfaces[0].indexVector.push(0,1,2,2,1,3);
			//墙顶
			border.surfaces[1].indexVector.push(0,1,2,2,1,3);
			//外墙
			border.surfaces[2].indexVector.push(3,2,1,1,2,0);
			
			//更新贴图大小
			//内墙
			shader = border.surfaces[0].material as Shader3D;
			var texFilter:TextureFilter = shader.filters[0] as TextureFilter;
			var point:Point = new Point(border.surfaces[0].vertexVector[0] - border.surfaces[0].vertexVector[16], border.surfaces[0].vertexVector[2] - border.surfaces[0].vertexVector[18]);
			texFilter.repeatX = point.length/150;
			//墙顶
			shader = border.surfaces[1].material as Shader3D;
			texFilter = shader.filters[0] as TextureFilter;
			point = new Point(border.surfaces[1].vertexVector[0] - border.surfaces[1].vertexVector[16], border.surfaces[1].vertexVector[2] - border.surfaces[1].vertexVector[18]);
			texFilter.repeatX = point.length/150;
			//外墙
			shader = border.surfaces[2].material as Shader3D;
			texFilter = shader.filters[0] as TextureFilter;
			point = new Point(border.surfaces[2].vertexVector[0] - border.surfaces[2].vertexVector[16], border.surfaces[2].vertexVector[2] - border.surfaces[2].vertexVector[18]);
			texFilter.repeatX = point.length/150;
			
			border.surfaces[0].upload(this.scene);
			border.surfaces[1].upload(this.scene);
			border.surfaces[2].upload(this.scene);
			
			this.addChild(border);
			
			return border;
		}
		
		public function isClockwise(x0:Number, y0:Number, x1:Number, y1:Number, x2:Number, y2:Number):Boolean
		{
			if (x0 * y1 + x1 * y2 + x2 * y0 - x1 * y0 - x2 * y1 - x0 * y2 <= 0)
				return true;
			else
				return false;
		}
	}
}